package net.chowda.castcluster.util;

import com.sun.syndication.feed.module.itunes.EntryInformationImpl;
import com.sun.syndication.feed.module.itunes.FeedInformationImpl;
import com.sun.syndication.feed.module.itunes.types.Duration;
import com.sun.syndication.feed.synd.*;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;
import com.sun.syndication.io.WireFeedInput;
import net.chowda.castcluster.Video;
import net.chowda.castcluster.playlist.PlayListManager;
import org.apache.log4j.Logger;
import org.xml.sax.InputSource;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * some utility methods for merging rss feeds.
 *
 * TODO this could be much smarter.
 */
public class RSSFeedAggregator {
    private static final Logger LOG = LogUtil.getLogger(PlayListManager.class);

    public static String createPodcastFromFeeds(String name, String description, List<String> feeds) throws CorruptFeedException {
        if(description == null || description.trim().length() == 0) {
            description = name;
        }

        SyndFeed baseFeed = getBaseFeed(name, description);

        try {
            List<SyndEntry> entries = new ArrayList<SyndEntry>(100);
            for (String feedStr : feeds) {
                SyndFeed feed = new SyndFeedImpl(new WireFeedInput().build(new InputSource(new StringReader(feedStr))));
                entries.addAll(feed.getEntries());
            }
            baseFeed.setEntries(entries);
            return new SyndFeedOutput().outputString(baseFeed);
        } catch (FeedException e) {
            throw new CorruptFeedException(e);
        }
    }

    public static String createPodcastFromVideos(String name, String description, List<Video> videos) throws CorruptFeedException {
        if(description == null || description.trim().length() == 0) {
            description = name;
        }

        SyndFeed baseFeed = getBaseFeed(name, description);

        for (Video video : videos) {
            SyndEntry entry = new SyndEntryImpl();

            long length = video.getLengthInSeconds();
            String dur = length / 60 + ":" + length % 60;

            // itunes stuff
            EntryInformationImpl iEntry = new EntryInformationImpl();
            iEntry.setDuration(new Duration(dur));
            iEntry.setExplicit(false);
            iEntry.setAuthor(video.getAuthor());
            iEntry.setSummary(video.getDescription());
            iEntry.setSubtitle(video.getAuthor() + ": " + video.getTitle());
            entry.getModules().add(iEntry);

            // normal stuff
            entry.setTitle(video.getTitle());
            entry.setAuthor(video.getAuthor());
            entry.setPublishedDate(video.getTimeUploaded());
            entry.setUpdatedDate(video.getTimeUploaded());
            entry.setLink(video.getUrl());

            SyndEnclosure enclosure = new SyndEnclosureImpl();
            enclosure.setType(video.getVidType());
            enclosure.setUrl(video.getUrl());
            enclosure.setLength(video.getVidSize());
            entry.setEnclosures(Arrays.asList(enclosure));

            SyndContent mediaDesc = new SyndContentImpl();
            mediaDesc.setType("text/plain");
            mediaDesc.setValue(video.getDescription());
            entry.setDescription(mediaDesc);
            baseFeed.getEntries().add(entry);

        }
        SyndFeedOutput output = new SyndFeedOutput();
        try {
            return output.outputString(baseFeed);
        } catch (FeedException e) {
            throw new CorruptFeedException("couldn't output feed... ", e);
        }
    }

    private static SyndFeed getBaseFeed(String name, String description) {
        SyndFeed feed = new SyndFeedImpl();

        FeedInformationImpl information = new FeedInformationImpl();
        information.setSubtitle(name);
        information.setSummary(description);
        information.setOwnerName("you");
        information.setOwnerEmailAddress("you@you.com");
        information.setAuthor("castcluster");

        feed.getModules().add(information);

        feed.setFeedType("rss_2.0");
        feed.setTitle(name);
        feed.setDescription(description);

        feed.setLanguage("en");
        feed.setLink(CastClusterConfig.getInstance().getGlobalProp(CastClusterConfig.BASE_URL));
        feed.setAuthor("castcluster");
        return feed;
    }
}
